package by.jabbby;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Date;

import android.os.SystemClock;
import android.util.Log;

public final class Logger {

	public static final boolean isLog = true;
	public static final boolean isDebug = true;
	private java.io.RandomAccessFile logFile;
	private static final String logName = "/sdcard/jabbby/jabbby.log";
	private static final String logFolder = "/sdcard/jabbby";
	private static Logger logger;
	private static final String TAG = "Logger";

	private static Logger getLogger() {
		if (logger == null) {
			logger = new Logger();
		}
		return logger;
	}

	private Logger() {
		try {
			File file = new File(logName);
			if (!file.exists()) {
				File folder = new File(logFolder);
				if (!folder.exists()) {
					// folder.createNewFile();
					folder.mkdirs();
				} else {
					if (!folder.isDirectory()) {
						folder.mkdirs();
					}
				}
				file.createNewFile();
			}
			logFile = new RandomAccessFile(file, "rwd");
			logFile.seek(file.length());
		} catch (Exception e) {
			e.printStackTrace();
			logger = null;
		}
	}
	
	
	
	private synchronized void writeE(String msg) {
		try {
			if(msg == null) return;
		logFile.writeUTF("\n");
		logFile.writeUTF("Error *******************"
				+ (new Date(SystemClock.currentThreadTimeMillis()))
						.toString() + "***********************");
		this.writeString(msg);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		
	}
	private synchronized void writeE(Throwable e) {
		try {
			if(e==null) return;
			logFile.writeUTF("\n");
			// logFile.writeUTF("*******************"+ (new Date(
			// SystemClock.currentThreadTimeMillis() )).toString()
			// +"***********************");
			writeString(e.getMessage());
			StackTraceElement[] ste = e.getStackTrace();
			if (ste != null) {
				for (int i = 0; i < ste.length; i++) {
					if(ste[i].getFileName().startsWith(Logger.class.getName())){
						continue;
					}
					logFile.writeUTF("\n at");
					logFile.writeUTF("\n ");
					writeString(ste[i].toString());
				}
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}

	private synchronized void writeString(String msg) {
		try {
			if(msg == null){
				return;
			}
			logFile.writeUTF("\n");
			logFile.writeUTF(msg);

		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}

	private synchronized void writeE(String msg, Throwable e) {
		try {
			logFile.writeUTF("\n");
			logFile.writeUTF("Error *******************"
					+ (new Date(SystemClock.currentThreadTimeMillis()))
							.toString() + "***********************");
			this.writeString(msg);
			this.writeE(e);			
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}
	
	private synchronized void writeI(String msg) {
		try {
			if(msg == null) return;
			logFile.writeUTF("\n");
			logFile.writeUTF("Info *******************"
					+ (new Date(SystemClock.currentThreadTimeMillis()))
							.toString() + "***********************");	
			this.writeString(msg);
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}
	
	private synchronized void writeW(String msg) {
		try {
			logFile.writeUTF("\n");
			logFile.writeUTF("Warning *******************"
					+ (new Date(SystemClock.currentThreadTimeMillis()))
							.toString() + "***********************");	
			this.writeString(msg);
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}
	
	private synchronized void writeD(String msg) {
		try {		
			logFile.writeUTF("\n");
			logFile.writeUTF("Debug *******************"
					+ (new Date(SystemClock.currentThreadTimeMillis()))
							.toString() + "***********************");
			this.writeString(msg);
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}

	public static void e(String msg) {

		getLogger().writeE(msg);
		Log.e(TAG, msg);

	}

	public static void e(String msg, Throwable tr) {
		getLogger().writeE(msg, tr);
		Log.e(TAG, msg, tr);
	}

	public static void e(Throwable tr) {
		getLogger().writeE(tr);
		Log.e(TAG, tr.getMessage(), tr);
	}

	public static void d( String msg) {
		getLogger().writeD(msg);
		Log.d(TAG, msg);
	}

	public static void i(String msg) {
		Log.i(TAG, msg);
		getLogger().writeI(msg);
	}	

	public static void w( String msg) {
		getLogger().writeW( msg);
	}

	

	

}
